﻿/*
* 创建者：LIYINFAI
* 创建时间：2023/10/15 11:40:00
* 描述：
* --------------------------------------
* 修改说明：
* --------------------------------------
*/
using CommonLibrary.Forms;
using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;

namespace CommonLibrary
{
    /// <summary>
    /// PLC管理窗体
    /// </summary>
    public partial class FormPLC : HWFrmWithTitle
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public FormPLC()
        {
            InitializeComponent();
            this.richTextBoxWriteLog.AllowDrop = true;
            this.richTextBoxWriteLog.DragEnter += RichTextBoxWriteLog_DragEnter;
            this.richTextBoxWriteLog.DragDrop += RichTextBoxWriteLog_DragDrop;
        }
        private void RichTextBoxWriteLog_DragDrop(object sender, DragEventArgs e)
        {
            var files = e.Data.GetData(DataFormats.FileDrop);
            if (files != null)
            {
                var data = files as string[];
                if (data != null && data.Length > 0)
                {
                    var splitArray = new string[] { "#,#" };
                    foreach (var f in data)
                    {
                        if (File.Exists(f))
                        {
                            string[] content = File.ReadAllLines(f, CommonHelper.ENCODING);
                            if (content != null && content.Length > 0)
                            {
                                foreach (var c in content)
                                {
                                    var items = c.Split(splitArray, StringSplitOptions.None);
                                    if (items != null && items.Length == 3)
                                    {
                                        var dataType = CommonHelper.GetEnumByName(items[1].Trim(), EDataType.SHORT);
                                        if (APPInstance.IsPLCConnected)
                                        {
                                            APPInstance.PLC.Write(dataType, items[0].Trim(), items[2].Trim());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        private void RichTextBoxWriteLog_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        private void AddReadLog(string tag, string message)
        {
            if (this.richTextBoxReadLog.InvokeRequired)
            {
                this.richTextBoxReadLog.Invoke(new Action(() => { AddReadLog(tag, message); }));
            }
            else
            {
                this.richTextBoxReadLog.AppendText($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}] {tag} => {message}\r\n");
                this.richTextBoxReadLog.ScrollToCaret();
                Application.DoEvents();
            }
        }
        private void AddWriteLog(string tag, string message)
        {
            if (this.richTextBoxWriteLog.InvokeRequired)
            {
                this.richTextBoxWriteLog.Invoke(new Action(() => { AddWriteLog(tag, message); }));
            }
            else
            {
                this.richTextBoxWriteLog.AppendText($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}] {tag} => {message}\r\n");
                this.richTextBoxWriteLog.ScrollToCaret();
                Application.DoEvents();
            }
        }
        private void SetPLCStatusString()
        {
            if (this.labelPLCStatus.InvokeRequired)
            {
                this.labelPLCStatus.Invoke(new Action(() => { SetPLCStatusString(); }));
            }
            else
            {
                Console.WriteLine("SetPLCStatusString");
                this.labelPLCStatus.Text = APPInstance.IsPLCConnected ? "PLC 连接状态：已连接" : "PLC 连接状态：已断开";
                this.labelPLCStatus.ForeColor = APPInstance.IsPLCConnected ? Color.White : Color.Red;
                Application.DoEvents();
            }
        }
        private Timer mTimer = null;
        private void SetTimer()
        {
            this.mTimer = new Timer();
            this.mTimer.Interval = 1000;
            this.mTimer.Tick += MTimer_Tick;
            this.mTimer.Start();
        }
        private void MTimer_Tick(object sender, EventArgs e)
        {
            SetPLCStatusString();
        }
        private void FormPLC_Load(object sender, EventArgs e)
        {
            InitControls();
            LoadPLCSetting();
            SetTimer();
            this.labelStart.Select();
        }
        private void InitControls()
        {
            this.comboBoxDevice.Items.Clear();
            this.comboBoxDevice.Items.AddRange(Enum.GetNames(typeof(EPLCDeviceType)));
            this.comboBoxDevice.SelectedItem = "OMRON";
            this.comboBoxReadDataType.Items.Clear();
            this.comboBoxReadDataType.Items.AddRange(Enum.GetNames(typeof(EDataType)));
            this.comboBoxReadDataType.SelectedItem = "SHORT";
            this.comboBoxWriteDataType.Items.Clear();
            this.comboBoxWriteDataType.Items.AddRange(Enum.GetNames(typeof(EDataType)));
            this.comboBoxWriteDataType.SelectedItem = "SHORT";
            this.comboBoxOptType.Items.Clear();
            this.comboBoxOptType.Items.AddRange(Enum.GetNames(typeof(EPLCOptType)));
            this.comboBoxOptType.SelectedItem = "FINS";
        }
        private void LoadPLCSetting()
        {
            var plcConfig = PLCHelper.GetPLCConfig();
            this.textBoxIP.Text = plcConfig.IP;
            this.textBoxPort.Text = plcConfig.Port.ToString();
            this.comboBoxDevice.SelectedItem = plcConfig.DeviceType.ToString();
            this.comboBoxOptType.SelectedItem = plcConfig.OptType.ToString();
            this.checkBoxIsStringReserve.Checked = plcConfig.IsStringReserve;
        }
        private void buttonSave_Click(object sender, EventArgs e)
        {
            CommonHelper.ShowWaiting(this, "数据保存中，请稍候......");
            if (GlobalStatus.APP == EAppStatus.RUN)
            {
                HWMessageBox.Show(this, "设备运行中，不允许修改参数");
                CommonHelper.CloseWaiting();
                return;
            }
            try
            {
                string ipString = this.textBoxIP.Text;
                string portString = this.textBoxPort.Text;
                EPLCDeviceType deviceType = CommonHelper.GetEnumByName(this.comboBoxDevice.SelectedItem.ToString(), EPLCDeviceType.OMRON);
                EDataFormat dataFormat = EDataFormat.CDAB;
                EPLCOptType optType = CommonHelper.GetEnumByName(this.comboBoxOptType.SelectedItem.ToString(), EPLCOptType.FINS);
                bool isStringReserve = this.checkBoxIsStringReserve.Checked;
                int port = 9600;
                if (!int.TryParse(portString, out port))
                {
                    HWMessageBox.Show(this, "端口有误");
                }
                else
                {
                    IPAddress ip = null;
                    if (!IPAddress.TryParse(ipString, out ip))
                    {
                        HWMessageBox.Show(this, "IP有误");
                    }
                    else
                    {
                        try
                        {
                            var plcConfig = PLCHelper.GetPLCConfig();
                            plcConfig.Port = port;
                            plcConfig.IP = ip.ToString();
                            plcConfig.DeviceType = deviceType;
                            plcConfig.DataFormat = dataFormat;
                            plcConfig.OptType = optType;
                            plcConfig.IsStringReserve = isStringReserve;
                            PLCHelper.SavePLCConfig(plcConfig);
                            APPInstance.ResetPLC();
                            LogHelper.Info($"修改PLC配置\r\n{CommonHelper.GetJsonString(plcConfig)}");
                            this.DialogResult = DialogResult.OK;
                            HWMessageBox.Show(this, "保存成功");
                        }
                        catch (Exception ex)
                        {
                            LogHelper.Error(ex);
                            HWMessageBox.Show(this, $"发生异常：{ex.Message}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                HWMessageBox.Show(this, $"发生异常：{ex.Message}");
            }
            CommonHelper.CloseWaiting();
        }
        private void buttonMaxSize_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            else
            {
                this.WindowState = FormWindowState.Maximized;
            }
        }
        private void FormPLC_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.mTimer?.Stop();
            this.mTimer?.Dispose();
        }
        private void buttonRead_Click(object sender, EventArgs e)
        {
            string address = this.textBoxReadAddress.Text;
            string lengthString = this.textBoxReadLength.Text;
            EDataType dataType = CommonHelper.GetEnumByName(this.comboBoxReadDataType.SelectedItem.ToString(), EDataType.SHORT);
            if (APPInstance.IsPLCConnected)
            {
                ushort length = 1;
                if (!ushort.TryParse(lengthString, out length))
                {
                    AddReadLog(address, "读取长度有误");
                }
                else
                {
                    try
                    {
                        var list = APPInstance.PLC.Read(dataType, address, length);
                        if (list != null && list.Count > 0)
                        {
                            AddReadLog(address, string.Join("\t", list));
                        }
                        else
                        {
                            AddReadLog(address, "没有数据");
                        }
                    }
                    catch (Exception ex)
                    {
                        AddReadLog(address, ex.Message);
                        LogHelper.Error(ex);
                        HWMessageBox.Show(this, $"发生异常：{ex.Message}");
                    }
                }
            }
            else
            {
                AddReadLog(address, "PLC有误，请确认PLC设备是否连接正常");
            }
        }
        private void buttonWrite_Click(object sender, EventArgs e)
        {

            string address = this.textBoxWriteAddress.Text;
            string value = this.textBoxWriteValue.Text;
            EDataType dataType = CommonHelper.GetEnumByName(this.comboBoxWriteDataType.SelectedItem.ToString(), EDataType.SHORT);
            if (APPInstance.IsPLCConnected)
            {
                try
                {
                    var result = APPInstance.PLC.Write(dataType, address, value);
                    AddWriteLog(address, $"{value}，{(result.result ? "成功" : (string.IsNullOrWhiteSpace(result.message) ? "失败" : result.message))}");
#if DEBUG
                    LogHelper.Debug($"【{this.Title}】【{address}】 写入结束：{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
#endif
                }
                catch (Exception ex)
                {
                    AddWriteLog(address, ex.Message);
                    LogHelper.Error(ex);
                    HWMessageBox.Show(this, $"发生异常：{ex.Message}");
                }
            }
            else
            {
                AddWriteLog(address, "PLC有误，请确认PLC设备是否连接正常");
            }

        }
        private void FormPLC_Shown(object sender, EventArgs e)
        {
        }
    }
}
